'''Sequence using iterator protocol defined with a generator'''
def __init__(self, seqn):
self.seqn = seqn
self.i = 0
def __iter__(self):
for val in self.seqn:
yield val
class X:
'''Missing __getitem__ and __iter__'''
def __init__(self, seqn):
self.seqn = seqn
self.i = 0
def next(self):
if self.i >= len(self.seqn):
raise StopIteration
v = self.seqn[self.i]
self.i += 1
return v
class N:
'''Iterator missing next()'''
def __init__(self, seqn):
self.seqn = seqn
self.i = 0
def __iter__(self):
return self
class E:
'''Test propagation of exceptions'''
def __init__(self, seqn):
self.seqn = seqn
self.i = 0
def __iter__(self):
return self
def next(self):
3 // 0
class S:
'''Test immediate stop'''
def __init__(self, seqn):
pass
def __iter__(self):
return self
def next(self):
raise StopIteration
from itertools import chain, imap
def L(seqn):
'''Test multiple tiers of iterators'''
return chain(imap((lambda x: x), R(Ig(G(seqn)))))
class TestVariousIteratorArgs(unittest.TestCase):
def test_constructor(self):
for s in ('123', '', range(1000), ('do', 1.2), xrange(2000, 2200, 5)):
for g in (G, I, Ig, S, L, R):
self.assertEqual(list(deque(g(s))), list(g(s)))
self.assertRaises(TypeError, deque, X(s))
self.assertRaises(TypeError, deque, N(s))
self.assertRaises(ZeroDivisionError, deque, E(s))
def test_iter_with_altered_data(self):
d = deque('abcdefg')
it = iter(d)
d.pop()
self.assertRaises(RuntimeError, it.next)
class Deque(deque):
pass
class DequeWithBadIter(deque):
def __iter__(self):
raise TypeError
class TestSubclass(unittest.TestCase):
def test_basics(self):
d = Deque(xrange(100))
d.__init__(xrange(100, 200))
for i in xrange(200, 400):
d.append(i)
for i in reversed(xrange(-200, 0)):
d.appendleft(i)
self.assertEqual(list(d), range(-200, 400))
self.assertEqual(len(d), 600)
left = [ d.popleft() for i in xrange(250) ]
self.assertEqual(left, range(-200, 50))
self.assertEqual(list(d), range(50, 400))
right = [ d.pop() for i in xrange(250) ]
right.reverse()
self.assertEqual(right, range(150, 400))
self.assertEqual(list(d), range(50, 150))
d.clear()
self.assertEqual(len(d), 0)
def test_copy_pickle(self):
d = Deque('abc')
e = d.__copy__()
self.assertEqual(type(d), type(e))
self.assertEqual(list(d), list(e))
e = Deque(d)
self.assertEqual(type(d), type(e))
self.assertEqual(list(d), list(e))
s = pickle.dumps(d)
e = pickle.loads(s)
self.assertNotEqual(id(d), id(e))
self.assertEqual(type(d), type(e))
self.assertEqual(list(d), list(e))
def test_pickle(self):
d = Deque('abc')
d.append(d)
e = pickle.loads(pickle.dumps(d))
self.assertNotEqual(id(d), id(e))
self.assertEqual(type(d), type(e))
dd = d.pop()
ee = e.pop()
self.assertEqual(id(e), id(ee))
self.assertEqual(d, e)
d.x = d
e = pickle.loads(pickle.dumps(d))
self.assertEqual(id(e), id(e.x))
d = DequeWithBadIter('abc')
self.assertRaises(TypeError, pickle.dumps, d)
def test_weakref(self):
d = deque('gallahad')
p = proxy(d)
self.assertEqual(str(p), str(d))
d = None
self.assertRaises(ReferenceError, str, p)
def test_strange_subclass(self):
class X(deque):
def __iter__(self):
return iter([])
d1 = X([
1,
2,
3])
d2 = X([
4,
5,
6])
d1 == d2
libreftest = '\nExample from the Library Reference: Doc/lib/libcollections.tex\n\n>>> from collections import deque\n>>> d = deque(\'ghi\') # make a new deque with three items\n>>> for elem in d: # iterate over the deque\'s elements\n... print elem.upper()\nG\nH\nI\n>>> d.append(\'j\') # add a new entry to the right side\n>>> d.appendleft(\'f\') # add a new entry to the left side\n>>> d # show the representation of the deque\ndeque([\'f\', \'g\', \'h\', \'i\', \'j\'])\n>>> d.pop() # return and remove the rightmost item\n\'j\'\n>>> d.popleft() # return and remove the leftmost item\n\'f\'\n>>> list(d) # list the contents of the deque\n[\'g\', \'h\', \'i\']\n>>> d[0] # peek at leftmost item\n\'g\'\n>>> d[-1] # peek at rightmost item\n\'i\'\n>>> list(reversed(d)) # list the contents of a deque in reverse\n[\'i\', \'h\', \'g\']\n>>> \'h\' in d # search the deque\nTrue\n>>> d.extend(\'jkl\') # add multiple elements at once\n>>> d\ndeque([\'g\', \'h\', \'i\', \'j\', \'k\', \'l\'])\n>>> d.rotate(1) # right rotation\n>>> d\ndeque([\'l\', \'g\', \'h\', \'i\', \'j\', \'k\'])\n>>> d.rotate(-1) # left rotation\n>>> d\ndeque([\'g\', \'h\', \'i\', \'j\', \'k\', \'l\'])\n>>> deque(reversed(d)) # make a new deque in reverse order\ndeque([\'l\', \'k\', \'j\', \'i\', \'h\', \'g\'])\n>>> d.clear() # empty the deque\n>>> d.pop() # cannot pop from an empty deque\nTraceback (most recent call last):\n File "<pyshell#6>", line 1, in -toplevel-\n d.pop()\nIndexError: pop from an empty deque\n\n>>> d.extendleft(\'abc\') # extendleft() reverses the input order\n>>> d\ndeque([\'c\', \'b\', \'a\'])\n\n\n\n>>> def delete_nth(d, n):\n... d.rotate(-n)\n... d.popleft()\n... d.rotate(n)\n...\n>>> d = deque(\'abcdef\')\n>>> delete_nth(d, 2) # remove the entry at d[2]\n>>> d\ndeque([\'a\', \'b\', \'d\', \'e\', \'f\'])\n\n\n\n>>> def roundrobin(*iterables):\n... pending = deque(iter(i) for i in iterables)\n... while pending:\n... task = pending.popleft()\n... try:\n... yield task.next()\n... except StopIteration:\n... continue\n... pending.append(task)\n...\n\n>>> for value in roundrobin(\'abc\', \'d\', \'efgh\'):\n... print value\n...\na\nd\ne\nb\nf\nc\ng\nh\n\n\n>>> def maketree(iterable):\n... d = deque(iterable)\n... while len(d) > 1:\n... pair = [d.popleft(), d.popleft()]\n... d.append(pair)\n... return list(d)\n...\n>>> print maketree(\'abcdefgh\')\n[[[[\'a\', \'b\'], [\'c\', \'d\']], [[\'e\', \'f\'], [\'g\', \'h\']]]]\n\n'